from selenium import webdriver
from PyQt5.QtWidgets import QApplication, QDesktopWidget
import os
import sys
import os
import re
import win32gui
import win32con
import threading
from bs4 import BeautifulSoup
# 创建会话
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QFileDialog
import openpyxl
from datetime import datetime
from PyQt5.QtGui import QTextCursor
import datetime
import random
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from PyQt5.QtWidgets import QApplication, QTabWidget, QMessageBox, QMenu, QMenuBar, QAction
import sys
import threading
from PyQt5.QtCore import pyqtSignal, QObject

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QMessageBox
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import (QApplication, QWidget, QComboBox, QLineEdit,
                             QPushButton, QTableView, QTextEdit, QVBoxLayout,
                             QLabel, QHBoxLayout, QMessageBox, QProgressBar,
                             QInputDialog)
from PyQt5.QtCore import QAbstractTableModel, Qt
from PyQt5.QtWidgets import QDesktopWidget
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QTableView
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel
from PyQt5.QtCore import Qt, QThread
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QTableView, QTextEdit, QScrollBar
import os
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
from PyQt5.QtCore import pyqtSignal, QObject
import openpyxl
import locale
import sys, time, random
import re
import string
from openpyxl import load_workbook
import requests
import pandas
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from lxml import etree
import pandas as pd
from selenium.webdriver.chrome.service import Service
from PyQt5.QtWidgets import QInputDialog
from trio import current_time
import shutil
import copy
import pandas as pd
from PyQt5.QtWidgets import QInputDialog

from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from subprocess import CREATE_NO_WINDOW
import traceback
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

desired_capabilities = DesiredCapabilities.CHROME
desired_capabilities["pageLoadStrategy"] = "none"

import winreg

user_agents = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 11.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
]


def generate_random_ua():
    return random.choice(user_agents)


# 208.70.10.96:5868:zftfnuiq:boknwrr5myt0
def driver_get(self, url):
    if self.useproxy == 1:
        reset_proxyip(self, self.driver)
    self.driver.get(url)


def has_ip_address(text):
    ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
    return bool(re.search(ip_pattern, text))


def reset_proxyip(self, driver, proxy):
    if proxy != '' and has_ip_address(proxy):
        proxy_1 = proxy.split(':')
        driver.proxy = {
            'http': f'http://{proxy_1[0]}:{proxy_1[1]}',
            'https': f'http://{proxy_1[0]}:{proxy_1[1]}'
        }


def getproxyip(self):
    proxyip = 'no proxy'
    original_str = "208.70.10.96:5868:zftfnuiq:boknwrr5myt0"
    parts = original_str.split(":")
    new_str = f"{parts[2]}:{parts[3]}@{parts[0]}:{parts[1]}"
    print(new_str)
    return new_str


class MessageSender(QObject):
    textUpdateSignal = pyqtSignal(str)
    progressUpdateSignal = pyqtSignal(int)


class SignalEmitter(QObject):
    buttonClickedSignal = pyqtSignal()


class TCrawl(QWidget):

    def __init__(self, userdata):
        super().__init__()
        self.waittime = 20
        self.drivers_tk=[]
        self.drivers_outlook=[]
        self.current_index=0
        #等到实际运行时，可以调整为更短一点
        self.bt1 = QPushButton('手动打开outlook验证码后==>传输给tiktok')
        self.locksend = threading.Lock()
        self.lock = threading.Lock()
        self.event = threading.Event()
        self.event.set()
        self.paused = False
        self.signal_emitter = SignalEmitter()
        self.bt1.clicked.connect(self.signal_emitter.buttonClickedSignal.emit)
        self.signal_emitter.buttonClickedSignal.connect(
            self.handle_button_click)
        self.driver = None
        self.driveroutlook = None
        self.pagetodb = 1
        #读取完3页，写数据库；

        #  每次显示进度条，每个时间间隔多少，比如如下为0.055,则间隔为random.random()*0.055
        self.progressbarsleep = 0.055
        self.processtasktimes = 0
        #执行任务次数
        self.button_1 = QPushButton('批量注册tkads工具')
        self.button_1.clicked.connect(lambda: self.parse_next_url(1))

        # self.button_transfer = QPushButton('手动打开outlook验证码后==>传输给tiktok')
        # self.button_transfer.clicked.connect(lambda: self.transferqr)

        self.scraper_thread = None
        self.outlook_thread = None

        self.driver = None
        self.random_ua = None
        menubar = QMenuBar(self)
        file_menu = QMenu('文件', self)
        close_action = QAction('关闭', self)
        file_menu.addAction(close_action)
        menubar.addMenu(file_menu)
        close_action.triggered.connect(self.closewindow)
        w_width = 1280
        w_height = 720
        desktop = QDesktopWidget()
        screen_rect = desktop.screenGeometry()
        percentage = 85
        width = int(screen_rect.width() * percentage / 100)
        height = int(screen_rect.height() * percentage / 100)
        self.resize(width, height)
        current_path = os.getcwd()
        intclientuse = 1  #是否客户使用
        self.tks=[]
        self.progress_bar = QProgressBar()

        #界面只保留登录界面，其他界面都是从数据库下载后执行；需要有一个版本控制系统
        """创建label_user按钮，与说明书"""
        """创建label_user关联输入"""
        # self.file_lable = QLabel('处理的文件名：')
        # self.entry_filepath = QLineEdit()
        # self.entry_filepath.setText('预处理ASIN数据后，这里显示导入的文件名。预处理的文件，第一行需要删除')
        self.textmemo = QTextEdit()
        self.sender = MessageSender()
        self.sender.textUpdateSignal.connect(self.textmemo.append)
        self.sender.progressUpdateSignal.connect(self.progress_bar.setValue)
        pre_layout = QHBoxLayout()
        self.button_2 = QPushButton('清除文本内容')
        self.button_2.clicked.connect(self.clearmemo)
        pre_layout.addWidget(self.button_1)
        pre_layout.addWidget(self.button_2)
        pre_layout.addWidget(self.bt1)
        main_layout = QVBoxLayout()
        main_layout.addWidget(menubar)  # 前置操作
        main_layout.addLayout(pre_layout)
        main_layout.addWidget(self.progress_bar)
        main_layout.addWidget(self.textmemo)
        self.setLayout(main_layout)
        self.setFocusPolicy(Qt.StrongFocus)

    def handle_button_click(self):
        self.textmemo.append('触发去读取outlook邮箱验证码')
        self.event.set()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Tab:
            self.textmemo.append('tab键盘按下了')
            self.handle_button_click()

    def on_return_pressed(self):
        print("回车被按下，触发了方法。")
        self.query_data()

    def closewindow(self):
        self.close()
    def keyPressEvent(self, event):
        if event.key() in  [Qt.Key_F2, Qt.Key_F1]:
            self.pause_tasks()
        elif event.key() in [Qt.Key_F11, Qt.Key_F12]:
            self.resume_tasks()

    def pause_tasks(self):
        QMessageBox.information(self, "提示", "线程已暂停")
        self.paused = True

    def resume_tasks(self):
        QMessageBox.information(self, "提示", "线程已继续")
        self.paused = False
    def reset_proxy(self, driver, original_proxystr):
        proxy = self.getproxyip(original_proxystr)
        if proxy != '' and has_ip_address(original_proxystr):
            # proxy_1 = proxy.split(':')
            driver.proxy = proxy

    def testproxy(self, original_proxystr):
        proxies = self.getproxyip(original_proxystr)
        start = int(round(time.time() * 1000))
        resp = None
        costTime = 0.0
        try:
            targetUrl = "http://myip.ipip.net"

            resp = requests.get(targetUrl, proxies=proxies, timeout=20)
            costTime = int(round(time.time() * 1000)) - start
            print(resp.text)
        except Exception as e:
            print(e)
            return 9999
        print("耗时：" + str(costTime) + "ms")

        return int(costTime / 1000)

    def getproxyip(self, proxystr):
        # original_str = "208.70.10.96:5868:zftfnuiq:boknwrr5myt0"
        # parts = proxystr.split(":")
        # new_str = f"{parts[2]}:{parts[3]}@{parts[0]}:{parts[1]}"
        proxies2 = {
            "http": f"http://{proxystr}",
            "https": f"https://{proxystr}"
        }
        print(proxies2)
        return proxies2

    def scroll_to_random_position(self, driver):
        # 获取页面的高度
        total_height = driver.execute_script(
            "return document.body.scrollHeight")
        random_position = random.randint(int(total_height * 0.7), total_height)
        driver.execute_script(f"window.scrollTo(0, {random_position});")

    def clearmemo(self):
        """定义触发事件2，删除文本框中内容"""
        self.textmemo.setText("")

    def readoutlook(self, row):
        print(f"long_running_task starting thread read outlook mail.")
        print(f'chuangjianreadoutlook{row}')
        self.sender.textUpdateSignal.emit(f'创建readoutlook{row}')

        driveroutlook = self.driveroutlook
        index = 0
        # if index ==0:
        #     continue
        mailbox = row[0]
        password2 = row[1]
        self.sender.textUpdateSignal.emit(f"开始读取邮箱{mailbox}:->密码{password2}-》 1")
        try:
            # proxy=self.getproxyip(proxy)
            print(f'chuangjianreadoutlook{row}:->2')

            driveroutlook.get("https://login.live.com/")
            self.sender.textUpdateSignal.emit(f"开始读取邮箱{mailbox}:->密码{password2}-》2 ")
            time.sleep(10 * random.random())
            b= "loginfmt" in driveroutlook.page_source
            self.sender.textUpdateSignal.emit(f"开始读取邮箱{mailbox}:->密码{password2}-》3 ")
            if b:
                self.sender.textUpdateSignal.emit(f"找到了邮箱 ")
            actions = ActionChains(driveroutlook)
            input_element = WebDriverWait(driveroutlook, 3).until(
                EC.element_to_be_clickable((By.NAME, "loginfmt")))
            
            while  input_element==None :
                input_element = WebDriverWait(driveroutlook, 3).until(
                EC.element_to_be_clickable((By.NAME, "loginfmt")))
            if input_element:
                actions.move_to_element(input_element).perform()
            self.sender.textUpdateSignal.emit(f"开始读取邮箱{mailbox}:->密码{password2}-》4 ")
            # for i in range(50):
            #     input_element.send_keys(Keys.BACKSPACE)
            inti = random.randint(0, 1)
            input_element.send_keys(mailbox)
            if inti == 0:
                input_element.send_keys(Keys.ENTER)
            else:
                button = driveroutlook.find_element(By.ID, "idSIButton9")
                button.click()  #need to wait
            self.sender.textUpdateSignal.emit(f"开始读取邮箱{mailbox}:->密码{password2}-》5 ")
            password_input = WebDriverWait(driveroutlook, 10).until(
                EC.element_to_be_clickable((By.ID, "i0118")))
            self.sender.textUpdateSignal.emit(f"开始读取邮箱{mailbox}:->密码{password2}-》7 ")
            # password_input = driveroutlook.find_element(By.ID, "i0118")
            # 进入输入密码的阶段
            # 输入密码
            self.sender.textUpdateSignal.emit(f"开始读取邮箱{mailbox}:->密码{password2}-》8 ")
            password_input.send_keys(password2)
            self.timesleep(0.2)
            password_input.send_keys(Keys.ENTER)
            self.timesleep(0.2)

            # element = WebDriverWait(driver, 10).until(
            #     EC.presence_of_element_located((By.ID, "your_element_id"))
            # 通过 id 定位按钮
            pagecontent = driveroutlook.page_source
            try:
                if 'iNext' in pagecontent:
                    next_button = WebDriverWait(driveroutlook, 1).until(
                        EC.element_to_be_clickable((By.ID, "iNext")))

                    # 点击按钮
                    if next_button:
                        next_button.click()
            except Exception as e:
                print(e)

            try:
                # 通过 id 定位链接
                if 'iShowSkip' in pagecontent:
                    skip_link = WebDriverWait(driveroutlook, 1).until(
                        EC.element_to_be_clickable((By.ID, "iShowSkip")))

                    # 点击链接
                    if skip_link:
                        skip_link.click()
            except Exception as e:
                print(e)
            try:
                if 'acceptButton' in pagecontent:
                    button = WebDriverWait(driveroutlook, 3).until(
                        EC.element_to_be_clickable((By.ID, "acceptButton")))

                    # 点击按钮
                    if button:
                        button.click()
            except Exception as e:
                print(e)

            # 然后进入driver.get
            # https://outlook.live.com/mail/0/
            # <span class="ms-Button-label label-161" id="id__213">接受</span>
            try:
                if 'ms-Button-label' in pagecontent:
                    accept_button = WebDriverWait(driveroutlook, 3).until(
                        EC.element_to_be_clickable(
                            (By.CSS_SELECTOR,
                             "span.ms-Button-label.label-161#id__213")))
                    # 点击按钮,接受
                    if accept_button:
                        accept_button.click()
            except Exception as e:
                print(e)


            for  ix in range(3):
                driveroutlook.get('https://outlook.live.com/mail/0/')
                urlout=driveroutlook.current_url
                if 'outlook.live.com/mail/0/' in urlout:
                    break
                time.sleep(random.random()*1.2)
                print(f'准备进入收件箱{ix+1}次')
                if 'iShowSkip' in pagecontent:
                    skip_link = WebDriverWait(driveroutlook, 1).until(
                        EC.element_to_be_clickable((By.ID, "iShowSkip")))   

                    # 点击链接
                    if skip_link:
                        skip_link.click()          
                    break
                if 'iNext' in pagecontent:
                    skip_link = WebDriverWait(driveroutlook, 1).until(
                        EC.element_to_be_clickable((By.XPATH, '//*[@id="iNext"')))  

                    # 点击链接
                    if skip_link:
                        skip_link.click()          
                    break
          
        except Exception as e:
            print(e)



    def parse_next_url(self, param):
        now = datetime.datetime.now()
        current_time = now.strftime("%Y-%m-%d %H:%M:%S")
        self.random_ua = random.choice(user_agents)

        headers = {"User-Agent": self.random_ua}
        current_path = os.getcwd()
        ver1 = get_chrome_version()
        driver = None

        self.textmemo.verticalScrollBar().setValue(
            self.textmemo.verticalScrollBar().maximum())
        self.textmemo.verticalScrollBar().setValue(
            self.textmemo.verticalScrollBar().maximum())
        if not self.scraper_thread or not self.scraper_thread.is_alive():
            if param == 1:
                self.scraper_thread = threading.Thread(
                    target=self.long_running_task, args=(self.event, ))
                print("Before starting thread.")
                self.scraper_thread.start()
                print("After starting thread.")
            # self.button_1.setEnabled(False)
    def long_running_task(self, event, param2=None):
        current_path = os.getcwd()
        filename = 'C:\Python312\lu.xlsx'
        # file_paths, _ = QFileDialog.getOpenFileNames(
        #             None, "请选择文件", "", "Excel 文件 (*.xls *.xlsx)")
        df = pd.read_excel(filename)
        screen = QApplication.primaryScreen().geometry()
        width = screen.width()
        height = screen.height()
        index=0
        # 2ge轮流打开；用前后方式：
        drivers=[]
        row=df.iloc[0]
        intmaxloop=len(df)
        index=0
        thd=threading.Thread(target=self.syctask,args=( event,df,index,intmaxloop,0))
        thd.start() 
    def syctask(self, event,df,index,intmaxloop,mini=0):      
        while self.paused :
            pass            

        row=df.iloc[index]
        mailbox = row[0]
        password2 = row[1]
        url = row[2]
        self.random_ua = random.choice(user_agents)
        headers = {"User-Agent": self.random_ua}
        chrome_options = Options()
        chrome_options.add_argument(f"user-agent={headers['User-Agent']}")
        chrome_options.add_argument('--disable-dev-shm-usage')
        chrome_options.add_argument("--no-sandbox")
        chrome_options.add_experimental_option('excludeSwitches',
                                                ['enable-automation'])
        chrome_options.add_argument('--ignore-certificate-errors')
        chrome_options.add_argument('--ignore-ssl-errors')
        # 创建一个webdriver实例
        chrome_options.add_argument('--disable-gpu-vsync')
        chrome_options.add_argument("--disable-web-security")
        chrome_options.add_argument("--disable-site-isolation-trials")
        current_path=os.getcwd()
        chromedriver_path = os.path.join(current_path, "chromedriver.exe")
        # 创建 Service 对象并传入路径
        service = Service(executable_path=chromedriver_path)
        # 创建 WebDriver 实例时传入 Service 对象和 ChromeOptions
        driver = webdriver.Chrome(service=service, options=chrome_options)
        driveroutlook = webdriver.Chrome(service=service,options=chrome_options)
        # 设置第一个浏览器在左边
        desktop = QDesktopWidget()
        width = desktop.screenGeometry().width()
        height = desktop.screenGeometry().height()
        
        if mini==0:
            driver.set_window_position(0, int(height * 0.05))
            driver.set_window_size(width / 2, height)
            # 设置第二个浏览器在右边
            driveroutlook.set_window_position(width / 2, int(height * 0.25))
            driveroutlook.set_window_size(width / 2, height)
        else:
            driver.set_window_position(0, int(height * 0.05))
            driver.set_window_size(width / 2, height)
            # 设置第二个浏览器在右边
            driveroutlook.set_window_position(width / 2, int(height * 0.25))
            driveroutlook.set_window_size(width / 2, height)

            driver.minimize_window()
            driveroutlook.minimize_window()

        self.drivers_tk.append(driver)
        self.drivers_outlook.append(driveroutlook)
        
        
        ver2 = driver.capabilities['chrome']['chromedriverVersion'].split(
            ' ')[0]

        proxy4 = self.getzlyproxyip(0)
        proxy5 = self.getzlyproxyip(1)

        self.sender.textUpdateSignal.emit(f'第{index+1}个收outlook邮箱，使用代理{proxy4}')
        self.sender.textUpdateSignal.emit(f'登录tiktok ads ，使用代理{proxy5}')

        self.reset_proxy(driver, proxy5)
        self.reset_proxy(driveroutlook, proxy4)

        try:
            self.sender.textUpdateSignal.emit(f'chromedriver版本{ver2}\n')
            driver.implicitly_wait(3)
            driveroutlook.implicitly_wait(3)
            self.driveroutlook = driveroutlook
            print(f'chuangjianreadoutlook{row}')
            self.outlook_thread = threading.Thread(target=self.readoutlook,
                                                    args=(row, ))
            print("Before starting thread.")
            self.outlook_thread.start()
            print("After starting thread.")
            # self.readoutlook(row)
            driver.get(url)
            intversion = 1
            # return
        
        except Exception as e:
            print(e)
        try:
            previous_title = driver.title
            previous_url = driver.current_url
            previous_source = driver.page_source            
            while True:
                current_title = driver.title
                current_url = driver.current_url
                current_source = driver.page_source
                pagecontent = driver.page_source

                title_changed = current_title!= previous_title
                url_changed = current_url!= previous_url
                source_changed = current_source!= previous_source

                if title_changed or url_changed or source_changed or 'Get Started' in driver.page_source or 'Start Now' in driver.page_source:
                    print("页面发生了变化")
                    break
                else:
                    print("页面未发生变化")

            previous_title = current_title
            previous_url = current_url
            previous_source = current_source
            input_getstart=None
        except Exception as e:
            print(e)
        try:
            if 'Get Started' in driver.page_source:
                input_getstart = WebDriverWait(driver, 1).until(
                    EC.element_to_be_clickable(
                        (By.XPATH, '//a[text()="Get Started"]')))
            if 'Start Now' in driver.page_source:
                    input_getstart = WebDriverWait(driver, 1).until(
                    EC.element_to_be_clickable(
                        (By.XPATH, '//*[@id="__layout"]/div/div[2]/div/section/section/section[1]/section/a')))
            if input_getstart:
                input_getstart.click()
                self.timesleep(0.2)
        except Exception as e:
            print(e)
        try:
            if 'btn-link' in driver.page_source:
                button = WebDriverWait(driver, 1).until(
                    EC.element_to_be_clickable(
                        (By.CSS_SELECTOR, '.btn-link.start')))
                button.click()
                intversion = 2
        except Exception as e:
            print(e)
        try:
            input_element = None
            previous_title = driver.title
            previous_url = driver.current_url
            previous_source = driver.page_source            
            while True and not 'Please enter your email address.' in driver.page_source:
                current_title = driver.title
                current_url = driver.current_url
                current_source = driver.page_source

                title_changed = current_title!= previous_title
                url_changed = current_url!= previous_url
                source_changed = current_source!= previous_source

                # if title_changed or url_changed or source_changed:
                if   url_changed or 'Please enter your email address.' in driver.page_source :
                    print("页面发生了变化")
                    break
                else:
                    print("页面未发生变化")
        except Exception as e:
            print(e)
        try:
            previous_title = current_title
            previous_url = current_url
            previous_source = current_source
            pagecontent = driveroutlook.page_source
            input_element=None
        except Exception as e:
            print(e)
        if 'Please enter your email address.' in driver.page_source:
            try:
                
                input_element = WebDriverWait(driver, 1).until(
                    EC.element_to_be_clickable((
                        By.CSS_SELECTOR,
                        "input[placeholder='Please enter your email address.']"
                    )))
            # 输入内容
            except Exception as e:
                print(e)
        try:
            if input_element:

                input_element.send_keys(mailbox)
            if "TikTokAds_Register-aggrement-guidline" in driver.page_source:
                checkbox = driver.find_element(
                    By.ID, "TikTokAds_Register-aggrement-guidline")
                # 选中复选框
                if checkbox and not checkbox.is_selected():
                    checkbox.click()
                
            input_element = WebDriverWait(driver, 2).until(
                EC.element_to_be_clickable((
                    By.CSS_SELECTOR,
                    "input[placeholder='Your password must be 6-20 characters']"
                )))
            # 输入内容
            if input_element:
                
                input_element.send_keys(f'{password2}@Zx')
                self.timesleep(0.2)
                input_element.send_keys(Keys.ENTER)
        except Exception as e:
            print(e)

        try:
            # <input type="text" placeholder="Please enter your password." minlength="0" maxlength="Infinity" class="bui-input bui-input-with-suffix bui-input-filled" name="repeatPwd" autocomplete="repeatPwd" style="padding-right: 32px;" data-gtm-form-interact-field-id="2">
            #输入确认密码
            if 'Please enter your password' in  driver.page_source:
                input_element = WebDriverWait(driver, 2).until(
                    EC.element_to_be_clickable(
                        (By.CSS_SELECTOR,
                        "input[placeholder='Please enter your password.']")))
                input_element.send_keys(f'{password2}@Zx')
            #发送验证码
            # <button type="button" class="bui-btn bui-btn-text byted-button bui-btn-md ac-sendcode-input__btn "><!---->
            # Send code
            # <!----></button>
            if 'ac-sendcode-input__btn' in  driver.page_source:
                button = WebDriverWait(driver, 2).until(
                    EC.element_to_be_clickable((
                        By.CSS_SELECTOR,
                        '.bui-btn.bui-btn-text.byted-button.bui-btn-md.ac-sendcode-input__btn'
                    )))
                button.click()

        except Exception as e:
            print(e)
        # tiktok注册需要验证码
        
        
        if index > 0:
            self.event.wait(5)
        if index <intmaxloop:
            self.event.set()
        while self.paused :
            pass

        if '//*[@id="TikTokAds_Register-formitems-verifycode"]/div/div/div[1]/span/button' in driver.page_source:
            input_element=driver.find_element(By.XPATH,'//*[@id="TikTokAds_Register-formitems-verifycode"]/div/div/div[1]/span/button')
            input_element.click()
            #发送验证码    

        validcode = '11111'


        try:
            pagecontent = driveroutlook.page_source
            while True:
                current_title = driver.title
                current_url = driver.current_url
                current_source = driver.page_source

                title_changed = current_title!= previous_title
                url_changed = current_url!= previous_url
                source_changed = current_source!= previous_source
                print("不知道页面是否变化，如果变化了，会打印-发送验证码之后。")
                if  url_changed :
                    print("页面发生了变化")
                    break
                else:
                    pass
        except Exception as e:
            print(e)
        
        #读取outlook验证码
        try:
            previous_title = current_title
            previous_url = current_url
            previous_source = current_source
            pagecontent = driveroutlook.page_source
            driveroutlook = self.driveroutlook
            pagecontent_outlook=driveroutlook.page_source
            if 'tiktok' in pagecontent_outlook.lower() : 
                text_element = WebDriverWait(driveroutlook, 5).until(
                    EC.element_to_be_clickable((
                        By.XPATH,
                        '//*[@id="x_bodyTable"]/tbody/tr[2]/td/table/tbody/tr[4]/td/table/tbody/tr/td'
                    )))
                print(text_element)
                text = text_element.text
                print(text)
                validcode = text
        except Exception as e:
            # QMessageBox.information(self, f"提示", "outlook邮箱出现tiktok验证码后，再点击此按钮哦！{e}")

            print(e)
        
        if validcode !='111111' and 'sendcode-separate-input' in pagecontent:
            try:
           
                vals = list(validcode)
                intkx = 0
                input_elements = driver.find_elements(
                    By.XPATH,
                    '//*[@id="ac-sendcode-separate-input"]/div/input')
                if input_elements:
                    pinput = None
                    for pinput in input_elements:
                        pinput.send_keys(vals(intkx))
                        intkx += 1
                    pinput.send_keys(Keys.ENTER)
            except Exception as e:
                print(e)
        if validcode !='111111' and   'Enter verification code' in pagecontent :
            try:
                 
                input_element = WebDriverWait(driver, 3).until(
                        EC.element_to_be_clickable(
                            (By.CSS_SELECTOR,
                            "input[placeholder='Enter verification code']")))
                intkx = 0

                if input_element:
                    input_element.send_keys(validcode)
                    input_element.send_keys(Keys.ENTER)
                    intkx += 1

            except Exception as e:
                print(e)

        # 模拟输入tiktok验证码

        # 输入完毕验证码，确定，再输入联系人信息

        # proxy_with_auth = "208.70.10.96:5868: zftfnuiq : boknwrr5myt0 "
        # if intversion==2:+
        try:
            previous_title = driver.title
            previous_url = driver.current_url
            previous_source = driver.page_source            
            pagecontent = driveroutlook.page_source
            while True:
                current_title = driver.title
                current_url = driver.current_url
                current_source = driver.page_source

                title_changed = current_title!= previous_title
                url_changed = current_url!= previous_url
                source_changed = current_source!= previous_source
                print("不知道页面是否变化enter verification code之后，如果变化了，会打印出来 ")
                if  url_changed :
                    print("页面发生了变化")
                    break
                else:
                    # print("页面未发生变化enter verification code之后 ")
                    pass
        except Exception as e:
                print(e)
        
                # 此时打开下一个线程,线程最小化
        thd=threading.Thread(target=self.syctask,args=( event,df,index + 1,intmaxloop,1))
        thd.start() 
        alphabet = string.ascii_lowercase  # 获取小写字母表
        first_char = random.choice(alphabet)
        int7x = random.randint(5, 7)
        int7y = random.randint(5, 9)
        second_char = alphabet[(alphabet.index(first_char) + int7x) %
                                len(alphabet)]
        third_char = alphabet[(alphabet.index(second_char) + int7y) %
                                len(alphabet)]
        bname = row[3]
        # while True:
        #     current_url = driver.current_url.lower()
        #     if "" in current_url:
        #         break
        


        try:
            if ' ' in bname:

                bname = bname.split(' ')[0].strip()
            bsname = f"{bname}{first_char}{second_char}{third_char} LLC".upper(
            )
            print(bsname)
            if 'Business Name' in driver.page_source:
                previous_title = driver.title
                previous_url = driver.current_url
                previous_source = driver.page_source  
                input_element = WebDriverWait(driver, 10).until(
                    EC.element_to_be_clickable(
                        (By.XPATH, "//input[@placeholder='Business Name']")))
                if input_element:
                    input_element.send_keys(bsname)
        except Exception as e:
            print(e)
        try:
            if 'Legal name of business' in driver.page_source:
                previous_title = driver.title
                previous_url = driver.current_url
                previous_source = driver.page_source  
                input_element = WebDriverWait(driver, 3).until(
                    EC.element_to_be_clickable(
                        (By.XPATH,
                        "//input[@placeholder='Legal name of business']")))
                if input_element:
                    input_element.send_keys(bsname)
        except Exception as e:
            print(e)               

        try:
            if 'vi-checkbox__inner' in driver.page_source:
                checkbox = WebDriverWait(driver, 2).until(
                    EC.presence_of_element_located(
                        (By.CSS_SELECTOR, '.vi-checkbox__inner')))
                checkbox.click()
        except Exception as e:
            print(e)
        try:
            if 'bui-checkbox-input' in driver.page_source:
                checkbox = WebDriverWait(driver, 2).until(
                    EC.presence_of_element_located(
                        (By.XPATH, '//input[@class="bui-checkbox-input"]')))
                checkbox.click()
        except Exception as e:
            print(e)
        sphone = row[4]
        if sphone:
            sphone = sphone.replace('(+1)', '').replace('-', '')
        print(bsname)

        print(sphone)

    
    
    

        try:
            if 'Enter mobile phone number' in driver.page_source:
                input_element = WebDriverWait(driver, 1).until(
                    EC.presence_of_element_located(
                        (By.XPATH,
                        "//input[@placeholder='Enter mobile phone number']")))
                input_element.send_keys(sphone)
                input_element.send_keys(Keys.ENTER)
        except Exception as e:
            print(e)

        try:
            if 'Submit' in driver.page_source:
                input_element = WebDriverWait(driver, 1).until(
                    EC.presence_of_element_located(
                        (By.XPATH,
                        '//*[@id="formAnchor"]/div/div/form')))
                input_element.send_keys(sphone)
                input_element.send_keys(Keys.ENTER)
        except Exception as e:
            print(e)
        while True:
                    current_title = driver.title
                    current_url = driver.current_url
                    current_source = driver.page_source

                    title_changed = current_title!= previous_title
                    url_changed = current_url!= previous_url
                    source_changed = current_source!= previous_source

                    if  url_changed :
                        print("页面发生了变化-录入了电话，企业名称信息")
                        break
                    else:
                        print("页面未发生变化-录入了电话，企业名称信息")
        try:
            driver.quit()
            driveroutlook.quit()
        except Exception as e:
            print(e)
        tk_dict = {
            'tkaccountmail': mailbox,
            'tkpassword': f'{password2}@Zx',
            'mailboxpassword': password2,
            'url': url,
            'phone': sphone
        }
        

        # self.drivers_tk[index+1].set_window_position(0, int(height * 0.05))
        # self.drivers_tk[index+1].set_window_size(width / 2, height)
        # # 设置第二个浏览器在右边
        # self.drivers_outlook[index+1].set_window_position(width / 2, int(height * 0.25))
        # self.drivers_outlook[index+1].set_window_size(width / 2, height)
        
        self.tks.append(tk_dict)
        self.sender.textUpdateSignal.emit(f"第{index+1}行,{tk_dict}处理数据正确 ")
        self.sender.progressUpdateSignal.emit(
            int((index + 1) * 100 / len(df)))
        time.sleep(self.waittime)
        
        self.sender.textUpdateSignal.emit("抓取完成。")
        current_path = os.getcwd()
        now = datetime.datetime.now()

        current_time = now.strftime("%Y-%m-%d %H:%M:%S")
        current_time = re.sub(r'\s', '',
                            now.strftime("%Y-%m-%d %H:%M:%S")).replace(
                                ':', '').replace(' ', '').replace('-', '')
        filesave = f'{current_path}\\output{current_time}.xlsx'

        df2 = pd.DataFrame(self.tks)
        df2.to_excel(filesave, index=False)
        for ix in range(4):
            self.sender.textUpdateSignal.emit(f'数据保存在{filesave}')

    def timesleep(self, index):
        time.sleep(index * random.random())

    def getzlyproxyip(self, param):
        #param=0，国内代理，否则为国际代理
        proxyip = 'no proxy'
        try:

            apiUrl = 'http://api.ipipgo.com/ip?cty=US&c=1&pt=1&ft=txt&pat=\n&rep=1&key=0c4201f3&ts=240'
            if param == 0:
                apiUrl = 'http://api.ip.data5u.com/dynamic/get.html?order=a0aab4a6ac5b39318e5317e8800a119d&random=2&sep=3'
            res = requests.get(apiUrl).content.decode()
            # 按照\n分割获取到的IP
            ips = res.split('\n')
            # 利用每一个IP
            for proxyip2 in ips:

                if proxyip2.strip() == '':
                    continue
                else:
                    proxyip = proxyip2
                print(proxyip2)

        except Exception as e:
            print(f'getproxyip{e}')

        return proxyip

    def disable_proxy():
        try:
            # 打开 Internet 设置的注册表项
            internet_settings = winreg.OpenKey(
                winreg.HKEY_CURRENT_USER,
                r'Software\Microsoft\Windows\CurrentVersion\Internet Settings',
                0, winreg.KEY_ALL_ACCESS)

            # 设置代理启用标志为 0（禁用代理）
            winreg.SetValueEx(internet_settings, 'ProxyEnable', 0,
                              winreg.REG_DWORD, 0)

            # 关闭注册表项
            winreg.CloseKey(internet_settings)
            print("代理已成功取消。")
        except Exception as e:
            print(f"出现错误：{e}")


def testproxy(original_str):
    original_str = "208.70.10.96:5868:zftfnuiq:boknwrr5myt0"
    parts = original_str.split(":")
    new_str = f"{parts[2]}:{parts[3]}@{parts[0]}:{parts[1]}"
    print(new_str)
    proxies = {"http": f"http://{new_str}", "https": f"https://{new_str}"}
    #
    start = int(round(time.time() * 1000))
    resp = None
    costTime = 0.0
    try:
        resp = requests.get(targetUrl, proxies=proxies, timeout=3)
        costTime = int(round(time.time() * 1000)) - start
        print(resp.text)
    except Exception as e:
        print(e)
        return 9999
    print("耗时：" + str(costTime) + "ms")
    return int(costTime / 1000)


def get_chrome_version():
    try:
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
                             r"Software\Google\Chrome\BLBeacon")
        version, _ = winreg.QueryValueEx(key, "version")
        winreg.CloseKey(key)
        return version
    except WindowsError:
        return None


def get_chrome_path():
    try:
        key = winreg.OpenKey(
            winreg.HKEY_LOCAL_MACHINE,
            r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe")
        value, _ = winreg.QueryValueEx(key, None)
        return value
    except FileNotFoundError:
        return None


def manscroll(driver):
    page_height = driver.execute_script("return document.body.scrollHeight")
    scroll_step = int(page_height / 3)  # 将滚动分为 100 步，可根据需要调整这个值
    for _ in range(3):
        driver.execute_script(f"window.scrollBy(0, {scroll_step});")
        time.sleep(0.15 * random.random())  # 可以根据需要调整滚动的速度，这里设置每步间隔 0.1 秒


if __name__ == '__main__':
    try:
        app = QApplication(sys.argv)
        userdata = {}
        ts = TCrawl(userdata)
        ts.show()

        ts.parse_next_url(1)
        app.exec_()
    except Exception as e:
        print(e)
